/*
 * Copyright 2008-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fsquare.controller.catalog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.broadleafcommerce.core.catalog.domain.Product;
import org.broadleafcommerce.core.catalog.service.CatalogService;
import org.broadleafcommerce.core.web.catalog.ProductHandlerMapping;
import org.broadleafcommerce.core.web.controller.catalog.BroadleafProductController;
import org.hibernate.tool.hbm2x.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fsquare.inventory.domain.SkuInventory;
import com.fsquare.inventory.domain.SkuMovement;
import com.fsquare.inventory.service.InventoryService;
import com.fsquare.inventory.service.InventoryUnavailableException;

/**
 * This class works in combination with the CategoryHandlerMapping which finds a category based upon
 * the passed in URL.
 */
@Controller("blProductController")
public class ProductController extends BroadleafProductController {
	
	@Resource(name = "fsquareInventoryService")
	protected InventoryService inventoryService;
	
	@Resource(name = "blCatalogService")
	protected CatalogService catalogService;
	
	protected static String MODEL_ATTRIBUTE_QUANTITY_NAME = "quantity";
	
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

    	ModelAndView model = new ModelAndView();
        Product product = (Product) request.getAttribute(ProductHandlerMapping.CURRENT_PRODUCT_ATTRIBUTE_NAME);
        assert(product != null);
        
        SkuInventory skuInventory = inventoryService.getInventory(product.getDefaultSku().getId());
        
        model.addObject(MODEL_ATTRIBUTE_QUANTITY_NAME, skuInventory.getQuantityAvailable());
        model.addObject(MODEL_ATTRIBUTE_NAME, product);
//        model.g
        if (StringUtils.isNotEmpty(product.getDisplayTemplate())) {
            model.setViewName(product.getDisplayTemplate());    
        } else {
            model.setViewName(getDefaultProductView());
        }
        return model;
    	
    	
    }
    @RequestMapping(value = "/product/get", produces = "application/json")
    @ResponseBody
    public Map<String, Object> getProductJson(HttpServletRequest request, HttpServletResponse response){
    	Map<String, Object> result = new HashMap<String, Object>();
    	String id = request.getParameter("productId");
    	List<String> errors = new ArrayList<String>();
    	if(id == null || id.equals("")){
    		errors.add("Invalid id");
    		result.put("errors", errors);
    		return result;
    	}
    		
        Product product = catalogService.findProductById(Long.parseLong(id));
        SkuInventory skuInventory = inventoryService.getInventory(product.getDefaultSku().getId());
        List<SkuMovement> skuMovements = inventoryService.getSkuMovements(product.getDefaultSku().getId());
        
        List<Map<String,Object>> movements = new ArrayList<Map<String,Object>>();
        for(SkuMovement skuMovement : skuMovements){
        	Map<String,Object> movement = new HashMap<String, Object>();
        	movement.put("id", skuMovement.getId());
        	movement.put("description", skuMovement.getDescription() != null?skuMovement.getDescription() :"");
        	movement.put("quantity", skuMovement.getQuantity());
        	movement.put("updateDate", skuMovement.getUpdateDate().toString());
        	movement.put("movementType", skuMovement.getMovementType());
        	if(skuMovement.getCustomer() != null)
        		movement.put("customer", skuMovement.getCustomer().getEmailAddress()+" ("+skuMovement.getCustomer().getId()+")");
        	else
        		movement.put("customer", "");

        	movements.add(movement);
        }
        	
        result.put("productId", product.getId());
        result.put("quantity", skuInventory.getQuantityAvailable());
        result.put("name", product.getName());
        result.put("description", product.getDescription());
        result.put("longDescription", product.getLongDescription());
        result.put("salePrice", product.getDefaultSku().getSalePrice());
        result.put("retailPrice", product.getDefaultSku().getRetailPrice());
        result.put("movements", movements);

    	return result;
    }
    
    @RequestMapping(value = "/product/updateInventory", produces = "application/json")
    @ResponseBody
    public Map<String, Object> updateInventory(HttpServletRequest request, HttpServletResponse response){
    	Map<String, Object> result = new HashMap<String, Object>();
    	String id = request.getParameter("productId");
    	String quantity = request.getParameter("quantity");
    	String inventoryAction = request.getParameter("inventoryAction");
    	List<String> errors = new ArrayList<String>();
    	if(id == null || id.equals("")){
    		errors.add("Invalid id");
    		result.put("errors", errors);
    		return result;
    	}
    	Product product = catalogService.findProductById(Long.parseLong(id));
        if(product == null){
        	errors.add("Product not found");
    		result.put("errors", errors);
    		return result;
        }
        
    	try {
    		SkuInventory newSkuInventory = null;
    		if(inventoryAction.equals("remove"))
    			newSkuInventory = inventoryService.decrementInventory(product.getDefaultSku().getId(), Integer.parseInt(quantity));
    		if(inventoryAction.equals("add"))
    			newSkuInventory = inventoryService.incrementInventory(product.getDefaultSku().getId(), Integer.parseInt(quantity));
    		if(newSkuInventory == null)
    			result.put("quantity", 0);
    		else
    			result.put("quantity", newSkuInventory.getQuantityAvailable());
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (InventoryUnavailableException e) {
			e.printStackTrace();
		}
    	
    	return result;
    }
    
    @RequestMapping(value = "/product/save", produces = "application/json")
    @ResponseBody
    public Map<String, Object> saveProduct(HttpServletRequest request, HttpServletResponse response){
    	Map<String, Object> result = new HashMap<String, Object>();
    	String id = request.getParameter("productId");
    	String name = request.getParameter("name");
    	String quantity = request.getParameter("quantity");
    	String description = request.getParameter("description");
    	String longDescription = request.getParameter("longDescription");
    	
    	System.out.println("ProductId: "+id);
//    	System.out.println("Quantity: "+quantity);
    	System.out.println("Name: "+name);
    	System.out.println("Description: "+description);
    	System.out.println("LongDescription: "+longDescription);
    	
    	
    	List<String> errors = new ArrayList<String>();
    	if(id == null || id.equals("")){
    		errors.add("Invalid id");
    		result.put("errors", errors);
    		return result;
    	}
    	
    	
    	
        Product product = catalogService.findProductById(Long.parseLong(id));
        if(product == null){
        	errors.add("Product not found");
    		result.put("errors", errors);
    		return result;
        }
        product.setDescription(description);
        product.setLongDescription(longDescription);
        product.setName(name);
        
        catalogService.saveProduct(product);
        
        SkuInventory skuInventory = inventoryService.getInventory(product.getDefaultSku().getId());
//        if(skuInventory.getQuantityAvailable())
        
    	return result;
    }
    
    
	public InventoryService getInventoryService() {
		return inventoryService;
	}

	public void setInventoryService(InventoryService inventoryService) {
		this.inventoryService = inventoryService;
	}
	public CatalogService getCatalogService() {
		return catalogService;
	}
	public void setCatalogService(CatalogService catalogService) {
		this.catalogService = catalogService;
	}

}
